001    package net.sf.xdc.processing;
002    
003    /*
004     *  Copyright 2005-2006 Jens Voß.
005     *
006     *  Licensed under the GNU Lesser General Public License (the "License");
007     *  you may not use this file except in compliance with the License.
008     *  You may obtain a copy of the License at
009     *
010     *       http://opensource.org/licenses/lgpl-license.php
011     *
012     *  Unless required by applicable law or agreed to in writing, software
013     *  distributed under the License is distributed on an "AS IS" BASIS,
014     *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
015     *  See the License for the specific language governing permissions and
016     *  limitations under the License.
017     */
018    
019    import java.io.BufferedReader;
020    import java.io.File;
021    import java.io.IOException;
022    import java.io.Writer;
023    import java.io.FileNotFoundException;
024    import java.text.NumberFormat;
025    import java.util.StringTokenizer;
026    import java.nio.charset.Charset;
027    
028    import net.sf.xdc.util.Logging;
029    import net.sf.xdc.util.IOUtils;
030    import org.apache.log4j.Logger;
031    
032    /**
033     * This class is responsible for generating HTML pages containing the
034     * contents of XML source files (in HTML format), decorated with line numbers
035     * and named anchors (enumerated by the current line numbers).
036     *
037     * @author Jens Voß
038     * @since 0.5
039     * @version 0.5
040     */
041    public class SourceProcessor {
042    
043      private static final Logger LOG = Logging.getLogger();
044      private static final NumberFormat NF = NumberFormat.getIntegerInstance();
045    
046      private static String escapeXml(String str) {
047        return str.replaceAll("&", "&").replaceAll("\"", """)
048                .replaceAll("<", "<").replaceAll(">", ">");
049      }
050    
051      private File outDir;
052    
053      /**
054       * Public constructor.
055       *
056       * @param outDir The output directory for this <code>SourceProcessor</code>
057       */
058      public SourceProcessor(File outDir) {
059        this.outDir = new File(outDir, "src-html");
060        this.outDir.mkdirs();
061      }
062    
063      /**
064       * This method is responsible for generating the HTML version of the source
065       * file specified by the <code>source</code> parameter.
066       *
067       * @param source The <code>XdcSource</code> object for which source HTML is
068       *        generated
069       * @param sourceEncoding The <code>Charset</code> used for interpreting the
070       *        source file
071       * @param targetEncoding The <code>Charset</code> used for writing to the
072       *        output file 
073       */
074      public void processSource(XdcSource source, Charset sourceEncoding, Charset targetEncoding) {
075    
076        File dir = new File(outDir, source.getPackageName());
077        dir.mkdirs();
078        BufferedReader in = null;
079        Writer out = null;
080        try {
081    
082          in = new BufferedReader(IOUtils.getReader(source.getFile(), sourceEncoding));
083          int lineNo = 0;
084          while (in.readLine() != null) {
085            lineNo++;
086          }
087          in.close();
088          in = null;
089    
090          int length = String.valueOf(lineNo).length();
091          NF.setMinimumIntegerDigits(length);
092          NF.setGroupingUsed(false);
093    
094          in = new BufferedReader(IOUtils.getReader(source.getFile(), sourceEncoding));
095    
096          out = IOUtils.getWriter(new File(dir, source.getFile().getName() + ".html"), targetEncoding);
097          out.write("<html><head><link href=\"");
098          StringTokenizer tok = new StringTokenizer(source.getPackageName(), "/.", false);
099          while (tok.hasMoreTokens()) {
100            tok.nextToken();
101            out.write("../");
102          }
103          out.write("stylesheet.css\" rel=\"stylesheet\" type=\"text/css\">");
104          out.write("</head><body><pre style=\"font-size:10pt;padding-bottom:1000px;\">\n");
105    
106          lineNo = 0;
107          String line;
108          while ((line = in.readLine()) != null) {
109            lineNo++;
110            out.write("<a name=\"line");
111            out.write(String.valueOf(lineNo));
112            out.write("\"/>");
113            out.write("<font color=\"green\"> ");
114            out.write(NF.format(lineNo));
115            out.write(" </font>     ");
116            out.write(escapeXml(line));
117            out.write('\n');
118          }
119          out.write("</pre></body></html>");
120        }
121        catch (FileNotFoundException e) {
122          LOG.error(e.getMessage(), e);
123        }
124        catch (IOException e) {
125          LOG.error(e.getMessage(), e);
126        }
127        finally {
128          try {
129            if (in != null) {
130              in.close();
131            }
132            if (out != null) {
133              out.close();
134            }
135          }
136          catch (IOException e) {
137            LOG.error(e.getMessage(), e);
138          }
139        }
140      }
141    
142    }